From 0fe22e1e37197ef6112645bf5a136580c0927a1e Mon Sep 17 00:00:00 2001 From: Roman Lebedev Date: Fri, 19 Aug 2016 21:01:03 +0300 Subject: [PATCH] babl_fish_reference(), create_name() are racy create_name_internal() uses global static buffer to create name. While this is definitely fast, it can't work concurrently. I used snprintf()+malloc()+snprintf(), so the amount of allocated memory for the string is optimal. Alternatively, a mutex would solve the problem, not sure which solution is faster / better. --- babl/babl-fish-reference.c | 43 ++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) diff --git a/babl/babl-fish-reference.c b/babl/babl-fish-reference.c index 4133e40..fe75a71 100644 --- a/babl/babl-fish-reference.c +++ b/babl/babl-fish-reference.c @@ -30,18 +30,45 @@ assert_conversion_find (const void *source, return ret; } +static char * +create_name_internal (char *buf, + size_t maxlen, + const Babl *source, + const Babl *destination, + int is_reference) +{ + return snprintf (buf, maxlen, "%s %p %p", + is_reference ? "ref " + : "", + source, destination); +} + static char * create_name (const Babl *source, const Babl *destination, int is_reference) { - static char buf[1024]; + int size = 0; + char *buf = NULL; + + size = create_name_internal (buf, size, source, destination, is_reference); + + if (size < 0) + return NULL; + + size++; /* For '\0' */ + buf = malloc (size); + if (buf == NULL) + return NULL; + + size = create_name_internal (buf, size, source, destination, is_reference); + + if (size < 0) + { + free (buf); + return NULL; + } - /* fish names are intentionally kept short */ - snprintf (buf, 1024, "%s %p %p", - is_reference ? "ref " - : "", - source, destination); return buf; } @@ -53,12 +80,15 @@ babl_fish_reference (const Babl *source, Babl *babl = NULL; char *name = create_name (source, destination, 1); + babl_assert (name); + babl = babl_db_exist_by_name (babl_fish_db (), name); if (babl) { /* There is an instance already registered by the required name, * returning the preexistent one instead. */ + free (name); return babl; } @@ -87,6 +117,7 @@ babl_fish_reference (const Babl *source, * name, inserting newly created class into database. */ babl_db_insert (babl_fish_db (), babl); + free (name); return babl; } -- 2.30.2